use std::{rc::Rc, cell::RefCell, thread::{self, JoinHandle}, time::Duration, sync::{Mutex, Arc, mpsc::channel}, collections::{HashSet, HashMap}};

use jvm_rust::raw;
use once_cell::sync::Lazy;

use crate::{native, rtda::{Frame, heap::{Class, string_pool}, self}, interpreter::{LINE, interpret}, classpath::WildcardEntry::new};

// 存活的线程
static SURVIVAL: Lazy<Arc<Mutex<HashSet<usize>>>> = Lazy::new(|| Arc::new(Mutex::new(HashSet::new())));

// 存储线程JoinHandle，用于Unsafe.unpark(),key为java thread object 内存地址, value为对应rust线程的JoinHandle
pub static THREADS: Lazy<Arc<Mutex<HashMap<usize, JoinHandle<()>>>>> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new())));


pub fn init() {
    native::register("java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", current_thread);
    native::register("java/lang/Thread", "yield", "()V", j_yield);
    native::register("java/lang/Thread", "sleep", "(J)V", sleep);
    native::register("java/lang/Thread", "start0", "()V", start0);
    native::register("java/lang/Thread", "isInterrupted", "(Z)Z", is_interrupted);
    native::register("java/lang/Thread", "isAlive", "()Z", is_alive);
    native::register("java/lang/Thread", "holdsLock", "(Ljava/lang/Object;)Z", holds_lock);
    
    native::register("java/lang/Thread", "setPriority0", "(I)V", set_priority0);
}

// public static native Thread currentThread();
// ()Ljava/lang/Thread;
fn current_thread(frame: Rc<RefCell<Frame>>) {
    let j_thread = frame.borrow().get_thread().lock().unwrap().get_j_thread();
    frame.borrow().get_operand_stack().borrow_mut().push_ref(j_thread);
}

// public static native void yield();
// ()V
fn j_yield(frame:  Rc<RefCell<Frame>>) {
    std::thread::yield_now()
}

// public static native void sleep(long millis) throws InterruptedException;
// (J)V
fn sleep(frame:  Rc<RefCell<Frame>>) {
    let vars = frame.borrow().get_local_vars();
    let millis = vars.borrow().get_long(0);
    std::thread::sleep(Duration::from_millis(millis as u64));
}


// start0最终调用的是Thread的run方法 https://blog.csdn.net/GuiRongGe/article/details/105920893
// private native void start0();
// ()V
fn start0(frame:  Rc<RefCell<Frame>>) {
    let vars = frame.borrow().get_local_vars();
    let stack = frame.borrow().get_operand_stack();

    // 线程对象
    let this = vars.borrow().get_this().unwrap();

    let key = this as usize;

    // 守护线程
    let daemon = unsafe { &*this }.get_boolean_var("daemon");

    // 线程优先级
    let mut priority = unsafe { &*this }.get_int_var("priority", "I");
    // 若为0用父线程优先级,即当前线程优先级
    if priority == 0 {
        let now_thread = frame.borrow().get_thread();
        let parent = now_thread.lock().unwrap().get_j_thread().unwrap();
        priority = unsafe { &*parent }.get_int_var("priority", "I");
        unsafe { &mut *this }.set_int_var("priority", "I", priority);
    }

    // 线程名称
    let name = unsafe { &*this }.get_ref_var("name", "Ljava/lang/String;").unwrap();
    let thread_name = string_pool::rs_string(name);
    // println!("thread_name: {}", thread_name);
    
    // 获取主线程发送者
    let sender = frame.borrow().get_thread().lock().unwrap().clone_sender();
    // println!("sender {}", sender.is_some());
    // 获取java线程run方法
    let run_method =   unsafe{ &*this }.get_class().get_thread_run_method().unwrap();
    
    // 新建线程对象
    let new_thread = Arc::new(Mutex::new(rtda::Thread::new_thread(sender)));
    new_thread.lock().unwrap().set_j_thread(Some(this));

    // 新建frame
    let new_frame = Frame::new_frame(new_thread.clone(), run_method);
    // 传入thread对象
    new_frame.get_local_vars().borrow_mut().set_ref(0, Some(this));
    new_thread.lock().unwrap().push_frame(new_frame);

    // 动态增加线程  
    let thread_handle = thread::Builder::new().name(thread_name.clone()).spawn(move || {  
        // 线程开始
        SURVIVAL.lock().unwrap().insert(key);

        if daemon {
            // 守护线程直接释放sender，因此不支持在守护线程中创建非守护线程。
            let sender = new_thread.lock().unwrap().take_sender();
            if let Some(sender) = sender {
                drop(sender); // 手动结束sender生命周期
            }
        }

        // 执行run方法
        interpret(new_thread.clone(), false);

        // 执行完成后释放sender
        let sender = new_thread.lock().unwrap().take_sender();
        if let Some(sender) = sender {
            drop(sender); // 手动结束sender生命周期
        }

        // 线程结束
        SURVIVAL.lock().unwrap().remove(&key);
        THREADS.lock().unwrap().remove(&key);
    });
    THREADS.lock().unwrap().insert(key, thread_handle.expect(&format!("线程: {} 创建失败！", thread_name)));
}


// 测试某些线程是否已中断。中断状态是否根据传递的 ClearInterrupted 值重置。
// private native boolean isInterrupted(boolean ClearInterrupted);
// (Z)Z
fn is_interrupted(frame:  Rc<RefCell<Frame>>) { // TODO 231218
    // let vars = frame.borrow().get_local_vars();
    // let this = vars.borrow().get_this().unwrap();
    // let b = vars.borrow().get_boolean(1);
	
    let stack = frame.borrow().get_operand_stack();
    stack.borrow_mut().push_boolean(false);
}

// 测试此线程是否处于活动状态。如果线程已启动且尚未终止，则该线程处于活动状态。
// 返回：true 如果此线程处于活动状态; false 否则。
// public final native boolean isAlive();
// ()Z
fn is_alive(frame:  Rc<RefCell<Frame>>) {
    let vars = frame.borrow().get_local_vars();
    let this = vars.borrow().get_this().unwrap();
    let key = this as usize;
    let alive = SURVIVAL.lock().unwrap().contains(&key);
	
    let stack = frame.borrow().get_operand_stack();
    stack.borrow_mut().push_boolean(alive);
}

// public static native boolean holdsLock(Object obj);
// (Ljava/lang/Object;)Z
fn holds_lock(frame:  Rc<RefCell<Frame>>) {
    let thread = frame.borrow().get_thread();

    let vars = frame.borrow().get_local_vars();
    let lock = vars.borrow().get_ref(0).unwrap();
    let key = lock as usize;

    let is_hold = thread.lock().unwrap().contains_lock(key);
	
    let stack = frame.borrow().get_operand_stack();
    stack.borrow_mut().push_boolean(is_hold);
}


// private native void setPriority0(int newPriority);
// (I)V
fn set_priority0(frame:  Rc<RefCell<Frame>>) {
    // let vars = frame.borrow().get_local_vars();
    // let this = vars.borrow().get_this().unwrap();
	// let new_priority = vars.borrow().get_int(1);
	// TODO
}


#[cfg(test)]
mod tests {
    use std::{sync::mpsc::{channel, Sender}, time::Duration, thread};
 

    // 测试使用本线程 channel() sender 创建新线程。
    // 守护线程未存储父级线程sender，守护线程创建的线程与自身生命周期一样长。
    #[test]
    #[ignore]
    fn test_thread() {
        let (sender, receiver) = channel::<i32>(); 
        threadmain(sender);
        for _ in receiver {
            
        }
    }
    // 模拟main线程
    fn threadmain(sender: Sender<i32>) {
        let sender1 = sender.clone();
        thread::spawn(move || { 
            drop(sender); 
            thread1();
        });
        thread::spawn(move || {  
            thread3(sender1);
        });
    }

    // main线程创建的守护线程
    fn thread1() {
        let (sender, receiver) = channel::<i32>(); 
        thread::spawn(move || { 
            thread2(sender);
        });
        for i in 1..10 {
            println!("守护线程-{}", i);
            std::thread::sleep(Duration::from_secs(1));
        }
        
        for _ in receiver {
            
        }
    }

    // 守护线程内创建的非守护线程
    fn thread2(f: Sender<i32>) {
        for i in 1..7 {
            println!("内部线程{}", i);
            std::thread::sleep(Duration::from_secs(1));
        }
        drop(f);
    }

    // main线程创建的非守护线程
    fn thread3(f: Sender<i32>) {
        for i in 1..3 {
            println!("非守护线程--{}", i);
            std::thread::sleep(Duration::from_secs(1));
        }
        drop(f);
    }
}